using Lockstep.Math;
using UnityEngine;

namespace Lockstep.Game {
    public class UnityGameViewService : BaseGameService, IGameViewService {
        Transform entityTrans;
        Transform mapRootTrans;
        Transform bulletRootTrans;
        public override void DoAwake(IServiceContainer services)
        {
            base.DoAwake(services);
            GameObject go = GameObject.Find("Entity");
            if (!go) {
                go = new GameObject("Entity");
                GameObject.DontDestroyOnLoad(go);
            }
            entityTrans = go.transform;
            go = GameObject.Find("Map");
            if (!go)
            {
                go = new GameObject("Map");
                GameObject.DontDestroyOnLoad(go);
            }
            mapRootTrans = go.transform;
            go = GameObject.Find("Bullet");
            if (!go)
            {
                go = new GameObject("Bullet");
                GameObject.DontDestroyOnLoad(go);
            }
            bulletRootTrans = go.transform;
        }
        public void BindView(BaseEntity entity, BaseEntity oldEntity = null){
            if (oldEntity != null) {
                if (oldEntity.ConfigId == entity.ConfigId) {
                    entity.engineTransform = oldEntity.engineTransform;
                    var obj = (oldEntity.engineTransform as Transform).gameObject;
                    var views = obj.GetComponents<IView>();
                    foreach (var view in views) {
                        view.BindEntity(entity,oldEntity);
                    }
                }
                else {
                    UnbindView(oldEntity);
                }
            }
            else {
                GameObject prefab = null;
                Transform root = null;
                if (entity is Entity e)
                {
                    prefab = _gameResourceService.LoadPrefab(e.ConfigId) as GameObject;
                    root = entityTrans;
                }
                else if (entity is MapItemEntity m) {
                    prefab = _gameResourceService.LoadMapItem(m.config) as GameObject;
                    root = mapRootTrans;
                }
                else if (entity is BulletEntity b)
                {
                    prefab = _gameResourceService.LoadBullet(b.config) as GameObject;
                    root = bulletRootTrans;
                }
                if (prefab == null) return;
                var obj = (GameObject) GameObject.Instantiate(prefab,
                    entity.transform.pos.ToVector3(),
                    Quaternion.Euler(new Vector3(0, 0, entity.transform.deg)), root);
                obj.name = $"{prefab.name}{entity.EntityId}_{PhysicSystem.GetCollider(entity)?.Id}" ;
                entity.engineTransform = obj.transform;
                var views = obj.GetComponents<IView>();
                if (views.Length <= 0) {
                    var view = obj.AddComponent<BaseEntityView>();
                    view.BindEntity(entity);
                }
                else {
                    foreach (var view in views) {
                        view.BindEntity(entity);
                    }
                }
            }
        }

        public void UnbindView(BaseEntity entity){
            entity.OnRollbackDestroy();
        }
    }
}